package demo.aop.aspectJ.aspect;

import demo.aop.service.Simple;

// 声明了两个切入点（Pointcut）分别是：staticInit()（该切入点的连接点是Simple类的静态代码块）, welcomeMethod(name)（该切入点的连接点是Simple对象的welcomeMethod方法）;
// 隐式的在前置通知和后置通知中声明了相同的切入点，该切入点的连接是Simple的构造方法。
// 上面使用到了Aspectj内置的5中通知类型的四种：
// before（连接点执行前通知）
// after returning(连接点正常完成后通知)，
// after throwing(连接点执行中发生异常后通知)，
// after(连接点完成后通知，无论正常还是异常)。
// 另外一种是around(环绕通知，在连接点执行前，执行完成后都通知)。
// 同时指定before，after,around将无发确定其执行的顺序，而且指定around通知后没必要存在before，after通知，around通知是可以实现这两种通知的效果的。
public aspect SimpleAspect {

	public pointcut staticInit() : staticinitialization(demo.aop.service.Simple);

	before() : staticInit() {
		System.out.println("[before]"
				+ thisJoinPointStaticPart.getSignature().getName());
	}

	after() returning() : staticInit() {
		System.out.println("[after returning]"
				+ thisJoinPointStaticPart.getSignature().getName());
	}

	before() : call(public demo.aop.service.Simple.new()) {
		System.out.println("[before]" + thisJoinPoint.getSignature().getName());
	}

	after() : call(public demo.aop.service.Simple.new()) {
		System.out.println("[after]" + thisJoinPoint.getSignature().getName());
	}

	public pointcut welcomeMethod(String name) : call(public String demo.aop.service.Simple.welcome(String)) && args(name);

	before(String name): welcomeMethod(name){
		System.out
				.println("[before]"
						+ thisJoinPoint.getTarget().getClass()
								.getCanonicalName() + "."
						+ thisJoinPoint.getSignature().getName()
						+ " args_name=" + name);
	}

	after(String name) returning(String retval) : welcomeMethod(name) {
		System.out.println("[after returning]"
				+ thisJoinPoint.getTarget().getClass().getCanonicalName() + "."
				+ thisJoinPoint.getSignature().getName() + " args_name=" + name
				+ " return_value =" + retval);

	}

	after(String name) : welcomeMethod(name){
		System.out
				.println("[after]"
						+ thisJoinPoint.getTarget().getClass()
								.getCanonicalName() + "."
						+ thisJoinPoint.getSignature().getName()
						+ " args_name=" + name);
	}

	after(String name) throwing(java.lang.Exception e) : welcomeMethod(name)
	 {
		System.out.println("[after throwing]"
				+ thisJoinPoint.getTarget().getClass().getCanonicalName() + "."
				+ thisJoinPoint.getSignature().getName() + " throwing="
				+ e.getMessage());
	}
/**
	String around(String name) : welcomeMethod(name){
    		System.out.println("[around]========start=========");
    		System.out
    				.println("[around]"
    						+ thisJoinPoint.getTarget().getClass()
    								.getCanonicalName() + "."
    						+ thisJoinPoint.getSignature().getName()
    						+ " args_name=" + name);
    		String retval = proceed(name);
    		System.out.println("[around]"
    				+ thisJoinPoint.getTarget().getClass().getCanonicalName() + "."
    				+ thisJoinPoint.getSignature().getName() + " args_name=" + name
    				+ " return_value=" + retval);
    		System.out.println("[around] modify return value append '!!!' = "
    				+ (retval = retval + "!!!"));
    		System.out.println("[around]========end=========");
    		return retval;
    	} **/
}